home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-11-27 | 9.8 KB | 385 lines | [TEXT/MPS ] |
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; XFNC 1385 stripDelim (T, D, C, X)
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; © 1987 Theodore S. Romano DMD
- ;
- ; If you want to see more, send me what you think it's worth:
- ; I would rather push keys then pick plaque — TSR
- ;
- ; 1413 Palisades Beach Rd.
- ; Peoples Republic of Santa Monica, CA 90401
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; processes the text in T under control of D, C, and X as described below
- ;
- ; T is the text to process.
- ; D is the list of delimiters
- ; C is a conversion control code
- ; X is a list of characters to remove
- ;
- ; D, C, and X are optional arguments.
- ; D defaults to:
- ; space comma tab return
- ;
- ; C defaults to empty, as does X.
- ;
- ; All occurances of any of the delimiters (D) are converted to occurances
- ; of the first delimiter in the list.
- ;
- ; Contiguous sequences of delimiters are converted to a single
- ; delimiter (the first one in the list).
- ;
- ; Leading and trailing delimiters are removed.
- ;
- ; The conversion control code (C) can be empty, in which case no
- ; conversion occurs, or it may begin with a conversion control code
- ; from the table below, followed by a colon.
- ;
- ; Any remaining characters in the conversion control code parameter
- ; must occur in pairs, the first being mapped onto the second.
- ;
- ; If the list of characters to remove (X) is not empty then those
- ; characters are deleted as they are encountered and are not
- ; copied to the result string.
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; COMPILE:
- ;
- ; asm stripDelim.a
- ; link -sn Main=stripDelim -sn STDIO=stripDelim ∂
- ; -sn INTENV=stripDelim -rt XFCN=1385 ∂
- ; stripDelim.a.o -o "HD:Home"
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- INCLUDE 'Traps.a'
- INCLUDE 'ToolEqu.a'
- INCLUDE 'QuickEqu.a'
- INCLUDE 'SysErr.a'
- INCLUDE 'SysEqu.a'
- INCLUDE 'HyperXCmd.a'
-
- STRING ASIS
- CASE OBJECT
-
- EXPORT stripDelim
- stripDelim PROC
- ;
- ; make room for the mapping table and save the registers we'll need
- ; our caller preserves registers D3-D7/A1-A5 for us
- ;
- LINK A6,#-256 ; character mapping table
- MOVEM.L D1/D2,-(SP) ; save registers
- ;
- ; check arguments
- ;
- MOVE.L 8(A6),A1 ; XCmdBlockPtr
- MOVE.L params(A1),A0 ; handle to source text
- ;
- ; make sure there is some text to process and allocate space for results
- ;
- _GetHandleSize ; for clone to hold result
- TST.L D0
- BEQ done ; empty source
- _NewHandle ; allocate place for result
- BNE done
- MOVE.L 8(A6),A1 ; XCmdBlockPtr
- MOVE.L A0,returnValue(A1) ; save handle to result
- ;
- ; flesh out mapping table, map each character onto itself
- ;
- MOVE.L #255,D0
- MOVE.L A6,A0
- mapFill: MOVE.B D0,-(A0)
- DBRA D0,mapFill
- ;
- ; setup case and character conversions
- ;
- noRemovals: CMP.W #3,(A1) ; have 3rd parameter ?
- BLT doDelims
- MOVE.L params+8(A1),A2 ; conversion list handle
- MOVE.L (A2),A3
- CLR.L D0
- nextCode: MOVE.B (A3)+,D0
- BEQ chkDelete ; empty string
- CMP.B #':',D0
- BEQ doMap
- SUB.B #'A',D0
- BGE.S @1
- BRA.S nextCode
- @1: CMP.B #'W'-'A',D0
- BGT.S nextCode
- ;
- ; we get here if we are likely to have a conversion code
- ;
- ADD.L D0,D0
- MOVE.W base(D0),D1
- JMP base(D1.W)
- base: DC.W cA-base ; A -- alpha, lower case letters
- DC.W @none-base ; B
- DC.W @none-base ; C
- DC.W cD-base ; D -- decimal, + - .
- DC.W @none-base ; E
- DC.W cF-base ; F -- flip (toggle state of entries)
- DC.W cG-base ; G -- garbage (non printing)
- DC.W @none-base ; H
- DC.W @none-base ; I
- DC.W @none-base ; J
- DC.W @none-base ; K
- DC.W cL-base ; L -- lower case (convert upper to)
- DC.W cM-base ; M -- mac symbols
- DC.W cN-base ; N -- numerals
- DC.W @none-base ; O
- DC.W cP-base ; P -- punctuation
- DC.W @none-base ; Q
- DC.W @none-base ; R
- DC.W cS-base ; S -- symbols
- DC.W cT-base ; T -- text only
- DC.W cU-base ; U -- upper case (lower to upper)
- DC.W cV-base ; V -- values (decimal & numerals)
- DC.W cW-base ; W -- white space
- @none BRA.S nextCode
- ;
- ; A (alpha) delete the lowercase letters
- ;
- cA: MOVE.L #'z'-'a',D1 ; from a to z
- LEA 'a'(A0),A2
- @1: CLR.B (A2)+
- DBRA D1,@1
- BRA.S nextCode
- ;
- ; D (decimal) delete the . - , and + symbols from the table
- ;
- cD: CLR.L '+'(A0)
- BRA.S nextCode
- ;
- ; F (flip table) flip the table entries
- ;
- cF: MOVE.W #255,D1
- MOVE.L A6,A2
- @1: MOVE.B -(A2),D0
- BEQ.S @2
- CLR.B (A2)
- BRA.S @3
- @2: MOVE.B D1,(A2)
- @3: DBRA D1,@1
- CLR.B (A0)
- BRA nextCode
- ;
- ; G (garbage) delete the non-printing characters
- ;
- cG: CLR.B $7F(A0) ; DEL
- MOVE.L #$07-$01,D1 ; from SO to US
- LEA $01(A0),A2
- @1: CLR.B (A2)+
- DBRA D1,@1
- MOVE.L #$1F-$0E,D1 ; from SO to US
- LEA $0E(A0),A2
- @2: CLR.B (A2)+
- DBRA D1,@2
- MOVE.L #$FF-$D9,D1 ; from char D9 to FF
- LEA $D9(A0),A2 ; first char to zap
- @3: CLR.B (A2)+
- DBRA D1,@3
- BRA nextCode
- ;
- ; L (lower case) convert the uppercase letters to lowercase
- ;
- cL: LEA 'A'(A0),A2 ; pointer to table entry for 'A'
- MOVE.B #'a'-'A',D0 ; what to add from each entry
- MOVE.L #25,D1 ; DBRA style count
- @1: ADD.B D0,(A2)+ ; convert entry to uppercase
- DBRA D1,@1 ; loop
- BRA nextCode
- ;
- ; M (macintosh characters) delete the macintosh non ascii characters
- ;
- cM: MOVE.L #$D8-$80,D1 ; from fishy A to fishy Y
- LEA $80(A0),A2
- @1: CLR.B (A2)+
- DBRA D1,@1
- BRA nextCode
- ;
- ; N (numbers) delete the digits 0 to 9
- ;
- cN: MOVE.L #'9'-'0',D1 ; from 0 to 9
- LEA '0'(A0),A2
- @1: CLR.B (A2)+
- DBRA D1,@1
- BRA nextCode
- ;
- ; P (punctuation) delete ! " ' , . / : ; ? _
- ;
- cP: LEA punctuation,A2 ; string with punctuation characters
- MOVE.L #11,D1
- @1: MOVE.B (A2)+,D0
- CLR.B 0(A0,D0)
- DBRA D1,@1
- BRA nextCode
- ;
- ; S (symbols) delete rest of standard symbols (not P or D)
- ;
- cS: LEA symbols,A2 ; string with symbol characters
- MOVE.L #17,D1
- @1: MOVE.B (A2)+,D0
- CLR.B 0(A0,D0)
- DBRA D1,@1
- BRA nextCode
- ;
- ; T (text only) delete everything but alphanumeric and punctuation
- ;
- cT: LEA 1(A0),A2 ; pointer to table entrys
- MOVE.L #'/'-1,D1 ; dbra count
- @1: CLR.B (A2)+ ; clear entry
- DBRA D1,@1 ; loop
- CLR.W '<'(A0) ; < =
- CLR.B '>'(A0) ; >
- CLR.B '^'(A0) ; ^
- CLR.B '`'(A0) ; `
- LEA '{'(A0),A2
- MOVE.L #255-'{',D1
- @2: CLR.B (A2)+
- DBRA D1,@2
- LEA punctuation,A2 ; string with punctuation characters
- MOVE.L #11,D1
- @3: MOVE.B (A2)+,D0
- MOVE.B D0,0(A0,D0)
- DBRA D1,@3
- BRA nextCode
- ;
- ; U (upper case) convert the lower case letters to upper case
- ;
- cU: LEA 'a'(A0),A2 ; pointer to table entry for 'a'
- MOVE.L #'a'-'A',D0 ; what to subtract from each entry
- MOVE.L #25,D1 ; DBRA style count
- @1: SUB.B D0,(A2)+ ; convert entry to uppercase
- DBRA D1,@1 ; loop
- BRA nextCode
- ;
- ; V (value only) delete everything but numeric and decimal
- ;
- cV: LEA 1(A0),A2 ; pointer to table entrys
- MOVE.L #'/'-1,D1 ; dbra count
- @1: CLR.B (A2)+ ; clear entry
- DBRA D1,@1 ; loop
- LEA ':'(A0),A2
- MOVE.L #255-':',D1
- @2: CLR.B (A2)+
- DBRA D1,@2
- MOVE.L #'+,-.','+'(A0)
- BRA nextCode
- ;
- ; W (white space) delete white space characters
- ;
- cW: MOVE.L #5,D1 ; from BS to CR
- LEA 8(A0),A2
- @1: CLR.B (A2)+
- DBRA D1,@1
- CLR.B ' '(A0)
- BRA nextCode
- ;
- ; setup character mapping, the remaining characters in the
- ; conversion string are paired. The first should be set to change
- ; into the second
- ;
- doMap: CLR.L D0
- CLR.L D1
- @next: MOVE.B (A3)+,D0
- BEQ.S chkDelete
- MOVE.B (A3)+,D1
- BEQ.S chkDelete
- MOVE.B D1,0(A0,D0)
- BRA.S @next
- ;
- ; check for optional arguments (deletion list)
- ;
- chkDelete: CMP.W #4,(A1) ; maximum number of arguments
- BLT.S doDelims
- ;
- ; map characters to remove onto nulls
- ;
- MOVE.L params+12(A1),A2 ; removals list
- MOVE.L (A2),A3
- CLR.L D0
- @next MOVE.B (A3)+,D0
- BEQ.S doDelims
- CLR.B 0(A0,D0)
- BRA.S @next
- ;
- ; now setup the list of delimiters
- ;
- doDelims: CMP.W #2,(A1) ; have 2nd parameter ?
- BLT.S defDelims
- MOVE.L params+4(A1),A2 ; handle to delimiters
- MOVE.L (A2),A3 ; pointer to delimiters
- BRA.S setDelims
- defDelims: LEA theDelims,A3
- setDelims: CLR.L D1
- MOVE.B (A3),D1 ; primary delimiter
- CLR.L D0
- @next: MOVE.B (A3)+,D0 ; next delimiter
- BEQ.S setupDone
- MOVE.B D1,0(A0,D0) ; map it onto first delimiter
- BRA.S @next
- ;
- ; finally, we can do what we started to — filtering the source text
- ; D1 is the primary delimiter
- ; A0 is a pointer to the mapping table
- ;
- setupDone: MOVE.L params(A1),A2 ; handle to source text
- MOVE.L (A2),A3
- MOVE.L D1,D2 ; save primary delimiter
- MOVE.L returnValue(A1),A2 ; handle to result text
- MOVE.L (A2),A1 ; pointer to space for result string
- ;
- ; processing loop; fetch the next character and map it
- ;
- scanLoop: MOVE.B (A3)+,D0
- BEQ.S atNull ; source ends
- MOVE.B 0(A0,D0),D0 ; map character
- BEQ.S scanLoop ; character deleted
- ;
- ; check for delimiters
- ;
- CMP.B D2,D0 ; is recent character a delimiter
- BNE.S copy ; nope, so copy it
- CMP.B D1,D0 ; yes, so if the previous was also
- BEQ.S scanLoop ; then skip it
- ;
- ; copy the accepted character to the result
- ;
- copy: MOVE.B D0,(A1)+
- MOVE.L D0,D1
- BRA.S scanLoop
- ;
- ; done, delete any trailing delimiter and shrink wrap result
- ;
- atNull: MOVE.L (A2),D0
- CMP.L D0,A1
- BEQ.S putResult
- CMP.B -1(A1),D2 ; was last char a delimiter
- BNE.S putResult
- SUB.L #1,A1 ; yes, delete it
- putResult: CLR.B (A1)+ ; append null to result
- MOVE.L A1,D0
- SUB.L (A2),D0 ; compute length to fix handle size
- MOVE.L A2,A0
- _SetHandleSize
- ;
- ; all done
- ;
- done: MOVEM.L (SP)+,D1/D2
- UNLK A6
- MOVEM.L (SP)+,A0/A1 ; get return address and parameter
- JMP (A0) ; return
- ;
- theDelims DC.B $20,$2C,$0D,$09,$00,$00
- punctuation DC.B '!"'',./:;?_[]'
- symbols DC.B '#$%&()*<=>@^`{|}\~'
- END
-